home *** CD-ROM | disk | FTP | other *** search
- Path: news.iag.net!news
- From: jatmon@iag.net (John R Buchan)
- Newsgroups: comp.lang.c
- Subject: Re: sscanf problems
- Date: 24 Jan 1996 15:09:29 GMT
- Organization: Internet Access Group, Orlando, Florida
- Message-ID: <4e5i39$2e6@news.iag.net>
- References: <4e4c2v$j2g@mathserv.mps.ohio-state.edu>
- NNTP-Posting-Host: pm2-orl16.iag.net
- X-Newsreader: WinVN 0.99.7
-
- In article <4e4c2v$j2g@mathserv.mps.ohio-state.edu>,
- cmongold@magnus.acs.ohio-state.edu says...
- >
- >Hello,
- > I'm sorry if this is an inappropriate topic, but I've tried
- >everything else. I can't seem to get sscanf to to separate a string
- >into various variable types. Here is an example:
- >
- >#include <stdio.h>
- >
- >void main()
-
- main must return int in any ansi c code. A return of void is undefined.
-
- >{
- >char input[20], crap[17], segment[6], seg_len[3], begin[3], load[3];
- >int type;
- >FILE *fp;
- >
- >printf("File: ");
- >gets(input);
-
- Use fgets(input, sizeof(input), stdin); This allows you to protect your
- array bounds. gets offers no such protection.
-
- >
- >fp = fopen(input, "r");
-
- I assume you've left out the tests for the sake of brevity?
-
- if( fp != NULL)
- {
- /* handle the failed open */
- }
-
- >
- >while(!feof(fp))
-
- The faq list explains why this test is not a good idea. Try:
-
- fgets(crap, sizeof(crap), fp);
-
- >{
- >fgets(crap, 17, fp);
-
- Avoid hard coding your sizes, when possible. Either use #defines or, if
- the buffer was defined as a char array, use sizeof.
-
- >sscanf(crap, "%d%3s%6s%3s%3s", type, begin, segment, seg_len, load);
-
- sscanf a pointer to a valid storage location for an object of the type
- indicated by the conversion specifier. You specified an int "%d", then
- passed the value of the uninitialized int 'type', instead of its address.
- You should have used &type. In a variable argument list, the compiler has
- no way of knowing the correct type of any passes argument. So, it can not
- warn you, when you pass the wrong type. You must make certain to pass the
- correct type.
-
- Since an array name decays to a pointer to its first element, you are
- correct with the types of the other arguments. However, you are not
- allowing room for the '\0' that sscanf will append. After sscanf reads 3
- chars and stores them in 'begin', it will add a '\0' to make 'begin' a legal
- string ("%s" indicates that you want a string). This means that it will
- actually store 4 chars in 'begin'. Since begin was defined for only 3, you
- just overwrote the first char of whatever happened to follow it in memory.
-
- If you want to literally read 3 chars and are not going to use them as a
- string, use "%3c". However, this specifier will not react to white spaces
- the same as "%s". So you need to look closely at it.
-
- You should make a point to test the return value of sscanf against the
- number of fields you expected to read. It is the only way to ensure that
- you actually read the correct number.
-
- >printf("%d %3s %6s %3s %3s", type, begin, segment, seg_len, load);
- >
-
- You will need a return statement here to match the correct definition of main.
-
- return 0;
-
- >}
- >}
- >No matter what I do, it always 'bus errors' when I sscanf. I've tried
- >it several different ways, including making crap larger, but to
- >no avail. If anyone can help me, I would greatly appreciate it.
-
- The bus error was most likely a result of your sscanf, not the fgets.
-
- Most of this is explained in the c.l.c faq (Frequently Asked Question) list.
- You can d/l it by anonymous ftp from rtfm.mit.edu /pubusenet/comp.lang.c.
-
- --
- John R Buchan -:|:- Looking for that elusive FAQ? ftp to:
- jatmon@mail.iag.net -:|:- rtfm.mit.edu /pub/usenet-by-group/....
-
-